package com.gzhryc.shared_device.oem.h5.mng.controllers.member;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import com.gzhryc.common.StringTools;
import com.gzhryc.common.data.dto.AjaxResult;
import com.gzhryc.common.data.dto.ListResult;
import com.gzhryc.common.excel.ExcelTools;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.kafka.JFKafkaProducer;
import com.gzhryc.common.kafka.KafkaProducerFactory;
import com.gzhryc.common.kafka.models.KafkaMessage;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.DateBranchHelper;
import com.gzhryc.servlet.DtoConstants;
import com.gzhryc.servlet.WebUtils;
import com.gzhryc.servlet.annotation.Route;
import com.gzhryc.shared_device.base.enums.EOperatorType;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.base.models.OrderLogContent;
import com.gzhryc.shared_device.oem.code.KafkaEventConstants;
import com.gzhryc.shared_device.oem.code.agent.dao.db.Agent;
import com.gzhryc.shared_device.oem.code.agent.services.AgentService;
import com.gzhryc.shared_device.oem.code.business.EBusinessType;
import com.gzhryc.shared_device.oem.code.member.dao.db.MemberBusinessOrder;
import com.gzhryc.shared_device.oem.code.member.dao.enums.MemberBusinessOrderEnum;
import com.gzhryc.shared_device.oem.code.member.services.MemberBusinessOrderService;
import com.gzhryc.shared_device.oem.code.member.services.dto.MemberBusinessOrderSearch;
import com.gzhryc.shared_device.oem.code.profit.dao.db.AgentReferrerOrderProfit;
import com.gzhryc.shared_device.oem.code.profit.dao.db.BusinessOrder;
import com.gzhryc.shared_device.oem.code.profit.dao.db.BusinessOrderLog;
import com.gzhryc.shared_device.oem.code.profit.dao.db.BusinessOrderUser;
import com.gzhryc.shared_device.oem.code.profit.dao.db.BusinessOrderUserProfit;
import com.gzhryc.shared_device.oem.code.profit.dao.enums.BusinessOrderEnum;
import com.gzhryc.shared_device.oem.code.profit.event.UserProfitCancelEvent;
import com.gzhryc.shared_device.oem.code.profit.event.UserProfitDivideEvent;
import com.gzhryc.shared_device.oem.code.profit.service.AgentReferrerOrderProfitService;
import com.gzhryc.shared_device.oem.code.profit.service.BusinessOrderLogService;
import com.gzhryc.shared_device.oem.code.profit.service.BusinessOrderService;
import com.gzhryc.shared_device.oem.code.profit.service.BusinessOrderUserProfitService;
import com.gzhryc.shared_device.oem.code.profit.service.BusinessOrderUserService;
import com.gzhryc.shared_device.oem.h5.mng.WebConstants;
import com.gzhryc.system.SysConstants;
import com.gzhryc.system.dao.db.Manager;

/**
 * 会员业务订单页面控制器
 * @version 2022-11-03
 */
public class MemberBusinessOrderController {

    static Logger log = Logger.getLogger(MemberBusinessOrderController.class);

    @Route(value = { "/member/order/list.html" })
    public String list(HttpServletRequest request) {
        request.setAttribute("dateBranchItemList", DateBranchHelper.self().getYearDateBranchItems());
        request.setAttribute("businessTypeList",EBusinessType.values());
        request.setAttribute("stateList",MemberBusinessOrderEnum.State.values());
        request.setAttribute("divideStateList",BusinessOrderEnum.DivideState.values());
        return "/member/order/list.html";
    }

    @Route(value = "/member/order/list.data")
    public ListResult<MemberBusinessOrder> listData(HttpServletRequest request) {
        ListResult<MemberBusinessOrder> result = new ListResult<>(DtoConstants.NULL_DATA, "暂无数据");
        MemberBusinessOrderSearch search = WebUtils.getParameter(request, MemberBusinessOrderSearch.class);
        Integer pageNo = WebUtils.getInteger(request, "page", 1);
        Integer pageLimit = WebUtils.getInteger(request, "limit", WebConstants.PAGE_LIMIT);
        Date createDate = new Date();
        if(StringTools.isNotBlank(search.getDateBranchId())){
            createDate = DateBranchHelper.getDateByItemId(search.getDateBranchId());
        }
        String searchDate = WebUtils.getString(request, "searchDate");
        if(StringTools.isNotBlank(searchDate)) {
	        String[] strings = searchDate.split(" - ");
	        if (strings.length == 2) {
	        	try {
	            Date startDate = DateUtils.parseDate(strings[0], "yyyy-MM-dd");
	            Date endDate = DateUtils.parseDate(strings[1], "yyyy-MM-dd");
	            
	            search.setStartCreateDate(startDate);
	            search.setEndCreateDate(endDate);
	     
	        	}catch(ParseException e) {
	        		result.setMsg("刷新时间解析失败");
	        		return result;
	        	}
	        }
        }

        result.getBody().setTotal(MemberBusinessOrderService.self(createDate).countJoinBySearch(search));
        List<MemberBusinessOrder> orderList = MemberBusinessOrderService.self(createDate).findJoinBySearch(search, pageNo, pageLimit);
        if (orderList != null && orderList.size() > 0) {
            result.setCode(DtoConstants.SUCCESS, null);
            result.getBody().setData(orderList);
        }
        return result;
    }

    @Route(value = { "/member/order/info.html" })
    public String info(HttpServletRequest request) {
        String tradeNo = WebUtils.getString(request,"tradeNo");
        Date createDate = WebUtils.getDate(request,"createDate");
        if(createDate == null){
            createDate = new Date();
        }
        MemberBusinessOrder businessOrder = MemberBusinessOrderService.self(createDate).getByTradeNo(tradeNo);
        if(businessOrder != null) {
            WebUtils.setAttribute(request, businessOrder);
        }
        return "/member/order/info.html";
    }

    @Route(value = "/member/order/user/list.data")
    public ListResult<BusinessOrderUser> userListData(HttpServletRequest request) {
        ListResult<BusinessOrderUser> result = new ListResult<>(DtoConstants.NULL_DATA, "暂无数据");

       String tradeNo = WebUtils.getString(request,"tradeNo");
        Date createDate = WebUtils.getDate(request,"createDate");
       if(StringTools.isNotBlank(tradeNo)) {
           if(createDate == null){
               createDate = new Date();
           }
           List<BusinessOrderUser> businessOrderList = BusinessOrderUserService.self(createDate).findJoinByTradeNo(tradeNo);
           if (businessOrderList != null && businessOrderList.size() > 0) {
               result.setCode(DtoConstants.SUCCESS, null);
               result.getBody().setData(businessOrderList);
           }
       }
        return result;
    }

    @Route(value = { "/member/order/user/refresh.do" })
    public AjaxResult doMemberRefresh(HttpServletRequest request) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "刷新失败");
        String tradeNo = WebUtils.getString(request, "tradeNo");
        Date createDate = WebUtils.getDate(request,"createDate");
        if (StringTools.isNotBlank(tradeNo)) {
            if(createDate == null){
                createDate = new Date();
            }
            try {
                if(BusinessOrderUserService.self(createDate).refresh(tradeNo)){
                    result.setCode(DtoConstants.SUCCESS,null);
                }
            } catch (LogicException e) {
                result.setMsg(e.getMessage());
            }
        }
        return result;
    }

    @Route(value = { "/member/order/operate.html" })
    public String operate(HttpServletRequest request, HttpServletResponse response) {
        String tradeNo = WebUtils.getString(request, "tradeNo");
        Date createDate = WebUtils.getDate(request, "createDate");
        if (createDate == null) {
            createDate = new Date();
        }
        MemberBusinessOrder businessOrder = MemberBusinessOrderService.self(createDate).getByTradeNo(tradeNo);
        if (businessOrder != null) {
            String createDateStr = DateFormatUtils.format(businessOrder.getCreateDate(), "yyyy-MM-dd HH:mm:ss");
            if(EBusinessType.CDCZ.index().equals(businessOrder.getBusinessType())){
                WebUtils.sendRedirect(request, response, "/cdcz/order/operate.html?tradeNo=" + tradeNo + "&createDate=" + createDateStr);
            }else if(EBusinessType.CDB.index().equals(businessOrder.getBusinessType())){
                WebUtils.sendRedirect(request, response, "/cdb/order/info.html?tradeNo=" + tradeNo + "&createDate=" + createDateStr);
            }else if(EBusinessType.BXSCN.index().equals(businessOrder.getBusinessType())){
                WebUtils.sendRedirect(request, response, "/bxscn/order/info.html?tradeNo=" + tradeNo + "&createDate=" + createDateStr);
            }else if(EBusinessType.BXSCN_SHOP.index().equals(businessOrder.getBusinessType())){
                WebUtils.sendRedirect(request, response, "/bxscn/shop_order/info.html?tradeNo=" + tradeNo + "&createDate=" + createDateStr);
            }else if(EBusinessType.PCL.index().equals(businessOrder.getBusinessType())){
                WebUtils.sendRedirect(request, response, "/pcl/order/info.html?tradeNo=" + tradeNo + "&createDate=" + createDateStr);
            }
        }
        return null;
    }

    @Route(value = { "/member/order/profit.html" })
    public String profitInfo(HttpServletRequest request) {
        String tradeNo = WebUtils.getString(request, "tradeNo");
        Date createDate = WebUtils.getDate(request, "createDate");
        if (createDate == null) {
            createDate = new Date();
        }
        BusinessOrder businessOrder = BusinessOrderService.self(createDate).getByTradeNo(tradeNo);
        if (businessOrder != null) {
            WebUtils.setAttribute(request, businessOrder);
        } else {
            MemberBusinessOrder memberBusinessOrder = MemberBusinessOrderService.self(createDate).getByTradeNo(tradeNo);
            if (memberBusinessOrder != null) {
                WebUtils.setAttribute(request, memberBusinessOrder);
                request.setAttribute("divideStateName", BusinessOrderEnum.DivideState.Wait.note());
                request.setAttribute("incomeMoneyStr", "--");
            }
        }
        
        //代理介绍人分成
        AgentReferrerOrderProfit referrerOrderProfit = AgentReferrerOrderProfitService.self(createDate).getByTradeNo(tradeNo);
        if(referrerOrderProfit != null) {
        	request.setAttribute("referrerOrderProfit", referrerOrderProfit);
        }
        
        return "/member/order/profit.html";
    }

    @Route(value = { "/member/order/profit/divide.do" })
    public AjaxResult profitDivide(HttpServletRequest request) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "分成失败");
        String tradeNo = WebUtils.getString(request, "tradeNo");
        if (StringTools.isNotBlank(tradeNo)) {
            JFKafkaProducer producer = KafkaProducerFactory.self().getProducer();
            if (producer != null) {
                Date createDate = WebUtils.getDate(request,"createDate");
                if(createDate == null){
                    createDate = new Date();
                }
                MemberBusinessOrder memberBusinessOrder = MemberBusinessOrderService.self(createDate).getByTradeNo(tradeNo);
                if(memberBusinessOrder == null) {
                    result.setMsg("未找到会员业务订单");
                    return result;
                }
                if(MemberBusinessOrderEnum.State.Finish.index().equals(memberBusinessOrder.getState())) {
                    Manager manager = WebUtils.getAttribute(request, SysConstants.LOGIN_MANAGER, Manager.class);
                    OperateInfo operateInfo = new OperateInfo(WebConstants.PROGRAM_TYPE,WebConstants.PROGRAM_TYPE_NAME);
                    operateInfo.setOperator( EOperatorType.Manager.index(),manager.getFullName());
                    operateInfo.setOperateNote("后台客服重新分成");

                    //触发分成
                    UserProfitDivideEvent profitDivideEvent = new UserProfitDivideEvent(memberBusinessOrder.getTradeNo(), memberBusinessOrder.getCreateDate(),operateInfo);
                    KafkaMessage kafkaMessage = new KafkaMessage(KafkaEventConstants.TOPIC_Order, KafkaEventConstants.KEY_ProfitDivide, JsonTools.toJson(profitDivideEvent));
                    if(producer.send(kafkaMessage)) {
                        //等待3秒后返回
                        try {
                            Thread.sleep(3000L);
                        } catch (InterruptedException e) {
                            //throw new RuntimeException(e);
                        }
                        result.setCode(DtoConstants.SUCCESS, null);
                    }
                }else{
                    result.setMsg("订单未完成，不允许分成");
                }
            } else {
                result.setMsg("消息队列未初始化");
            }
        }
        return result;
    }

    @Route(value = { "/member/order/profit/revoke.do" })
    public AjaxResult profitRevoke(HttpServletRequest request) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "回滚分成失败");
        String tradeNo = WebUtils.getString(request, "tradeNo");
        if (StringTools.isNotBlank(tradeNo)) {
            JFKafkaProducer producer = KafkaProducerFactory.self().getProducer();
            if (producer != null) {
                Date createDate = WebUtils.getDate(request,"createDate");
                if(createDate == null){
                    createDate = new Date();
                }

                BusinessOrder businessOrder = BusinessOrderService.self(createDate).getByTradeNo(tradeNo);
                if(businessOrder == null || !BusinessOrderEnum.DivideState.Finish.index().equals(businessOrder.getDivideState())){
                    result.setMsg("订单未分成或未分成成功，无法回滚");
                    return result;
                }

                Manager manager = WebUtils.getAttribute(request, SysConstants.LOGIN_MANAGER, Manager.class);
                OperateInfo operateInfo = new OperateInfo(WebConstants.PROGRAM_TYPE, WebConstants.PROGRAM_TYPE_NAME);
                operateInfo.setOperator(EOperatorType.Manager.index(), manager.getFullName());
                operateInfo.setOperateNote("后台客服回滚分成");

                UserProfitCancelEvent profitCancelEvent = new UserProfitCancelEvent(businessOrder.getTradeNo(), businessOrder.getCreateDate(), operateInfo);
                KafkaMessage kafkaMessage = new KafkaMessage(KafkaEventConstants.TOPIC_Order, KafkaEventConstants.KEY_ProfitCancel, JsonTools.toJson(profitCancelEvent));
                if(producer.send(kafkaMessage)){
                    //等待3秒后返回
                    try {
                        Thread.sleep(3000L);
                    } catch (InterruptedException e) {
                        //throw new RuntimeException(e);
                    }
                    //查询
                    businessOrder = BusinessOrderService.self(createDate).getByTradeNo(tradeNo);
                    if(BusinessOrderEnum.DivideState.Wait.index().equals(businessOrder.getDivideState())){
                    	result.setCode(DtoConstants.SUCCESS, null);
                    }
                }
            } else {
                result.setMsg("消息队列未初始化");
            }
        }
        return result;
    }

    @Route(value = "/member/order/profit/user/list.data")
    public ListResult<BusinessOrderUserProfit> userProfitListData(HttpServletRequest request) {
        ListResult<BusinessOrderUserProfit> result = new ListResult<>(DtoConstants.NULL_DATA, "暂无数据");
        String tradeNo = WebUtils.getString(request,"tradeNo");
        Date createDate = WebUtils.getDate(request,"createDate");
        if(StringTools.isNotBlank(tradeNo)) {
            if(createDate == null){
                createDate = new Date();
            }
            List<BusinessOrderUserProfit> userProfitList = BusinessOrderUserProfitService.self(createDate).findDivideByTradeNo(tradeNo);
            if (userProfitList != null && userProfitList.size() > 0) {
                result.setCode(DtoConstants.SUCCESS, null);
                result.getBody().setData(userProfitList);
            }
        }
        return result;
    }

    @Route(value = "/member/order/profit/operate/record/list.data")
    public ListResult<OrderLogContent.LogItem> logListData(HttpServletRequest request) {
        ListResult<OrderLogContent.LogItem> result = new ListResult<>(DtoConstants.NULL_DATA, "暂无数据");
        String tradeNo = WebUtils.getString(request,"tradeNo");
        Date createDate = WebUtils.getDate(request,"createDate");
        if(createDate == null){
            createDate = new Date();
        }
        BusinessOrderLog orderLog = BusinessOrderLogService.self(createDate).getByTradeNo(tradeNo);
        if(orderLog != null && StringTools.isNotBlank(orderLog.getContent())){
            OrderLogContent logContent = JsonTools.fromJson(orderLog.getContent(),OrderLogContent.class);
            if(logContent != null){
                result.setCode(DtoConstants.SUCCESS,null);
                result.getBody().setData(logContent.getItems());
            }
        }
        return result;
    }
    
    @Route(value = { "/member/order/excel/export/check.do" })
    public AjaxResult checkExportExcel(HttpServletRequest request, HttpSession session) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "导出检查失败");
        MemberBusinessOrderSearch search = WebUtils.getParameter(request, MemberBusinessOrderSearch.class);
        Date createDate = new Date();
        if(StringTools.isNotBlank(search.getDateBranchId())){
            createDate = DateBranchHelper.getDateByItemId(search.getDateBranchId());
        }
        session.setAttribute(WebConstants.SESSION_ORDER_EXPORT_EXECL_SEARCH,search);
        Long total = MemberBusinessOrderService.self(createDate).countJoinBySearch(search);
        result.setCode(DtoConstants.SUCCESS, null);
        result.setBody(total);
        return result;
    }

    @Route(value = "/member/order/excel/export.do")
    public void doExportExcel(HttpServletRequest request, HttpServletResponse response,HttpSession session) throws IOException {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        String name = format.format(new Date());
        String[] titles = { "订单编号","订单标题","会员ID","会员名称","会员手机号","代理ID","代理名称","设备类型名称","设备序列号","业务类型"
                ,"收费模式","网点ID","网点名称","网点地区","支付方式","订单金额","支付金额","钱包金额","优惠金额","优惠标题","订单状态","核销券状态","创建时间"};
        List<Object[]> data = new ArrayList<>();
        MemberBusinessOrderSearch search = WebUtils.getAttribute(session,WebConstants.SESSION_ORDER_EXPORT_EXECL_SEARCH,MemberBusinessOrderSearch.class);
        Date createDate = new Date();
        if(StringTools.isNotBlank(search.getDateBranchId())){
            createDate = DateBranchHelper.getDateByItemId(search.getDateBranchId());
        }
        Long total = MemberBusinessOrderService.self(createDate).countJoinBySearch(search);
        Integer pageNo = 1;
        Integer pageLimit = 100;
        Integer dataSize = 0;
        List<MemberBusinessOrder> orderList = MemberBusinessOrderService.self(createDate).findJoinBySearch(search, pageNo, pageLimit);
        while (orderList != null && orderList.size() > 0 && dataSize < total.intValue()) {
            List<Long> agentIds = new ArrayList<>();
            for (MemberBusinessOrder order : orderList) {
                agentIds.add(order.getAgentId());
            }

            List<Agent> agentList = AgentService.self().findJoinByUserIds(agentIds);
            for (MemberBusinessOrder order : orderList) {
                Object[] objects = new Object[titles.length];
                objects[0] = order.getTradeNo();
                objects[1] = order.getTitle();
                objects[2] = order.getMemberId();
                objects[3] = order.getMemberName();
                objects[4] = order.getMemberPhone();
                objects[5] = order.getAgentId();
                objects[6] = order.getAgentId();
                if(agentList != null && agentList.size() > 0){
                    for(Agent agent : agentList){
                        if(agent.getUserId().equals(order.getAgentId())){
                            objects[6] = agent.getUser().getFullName();
                            break;
                        }
                    }
                }
                objects[7] = order.getDeviceTypeName();
                objects[8] = order.getDeviceSn();
                objects[9] = order.getBusinessTypeName();
                objects[10] = order.getCostModeName();
                objects[11] = order.getPlaceId();
                objects[12] = order.getPlaceName();
                objects[13] = order.getAreaName();
                objects[14] = order.getPayTypeName();
                objects[15] = order.getMoneyStr();
                objects[16] = order.getPayMoneyStr();
                objects[17] = order.getWalletMoneyStr();
                objects[18] = order.getDiscountMoneyStr();
                objects[19] = order.getCouponTitle();
                objects[20] = order.getStateName();
                objects[21] = order.getVerificationVoucherStateName();
                objects[22] = DateFormatUtils.format(order.getCreateDate(),"yyyy-MM-dd HH:mm:ss");
                data.add(objects);
            }

            dataSize = dataSize + orderList.size();
            pageNo = pageNo + 1;
        }
        WebUtils.exportExcel(response, name);
        ExcelTools.export(response.getOutputStream(), "业务订单信息", null, titles, data);
    }
}
